2014/02/10

Recent entries from same category

  1. RapidJSON や simdjson よりも速いC言語から使えるJSONライブラリ「yyjson」
  2. コメントも扱える高機能な C++ 向け JSON パーサ「jsoncpp」
  3. C++ で flask ライクなウェブサーバ「clask」書いた。
  4. C++ 用 SQLite3 ORM 「sqlite_orm」が便利。
  5. zsh で PATH に相対パスを含んだ場合にコマンドが補完できないのは意図的かどうか。

C言語の文字列伸張は慣れないとコストの掛かるコーディングになりがちです。
またそういった文字列ライブラリというのは、直接 puts や printf に放り込めないという難点があります。
しかし sds というライブラリは異なります。
antirez/sds - GitHub

Simple Dynamic Strings SDS is a string library for C designed to augment the limited libc ...

https://github.com/antirez/sds
通常、C言語向け文字列ライブラリというのは独自の構造体ポインタを返します。そうする事で、文字列ポインタ以外の情報を詰め込んで処理する事が出来ます。しかしその反面、構造体ポインタをそのまま puts や printf に放り込めず、何かしらのアクセサを用意する必要がありました。 printf("%s\n", string->buf);
しかし sds の場合はそれが出来ます。 printf("%s\n", sds_string); sds *tokens;
int count, j;

sds line = sdsnew("Hello World!");
tokens = sdssplitlen(line,sdslen(line)," ",1,&count);

for (j = 0; j < count; j++)
    printf("%s\n", tokens[j]);
sdsfreesplitres(tokens,count);

output> Hello
output> World!
トリックとしては、sds で生成された文字列は必ず sds 構造体のメンバに格納されている前提ですので、sds 文字列ポインタは構造体の先頭ポインタからのオフセット分シフトした所に位置します。
つまり sds 文字列ポインタからヘッダのバイト数分アドレスを戻せば、補足情報を得られるという仕組みです。
それの証拠に sdslen は以下の様なコードになっています。
static inline size_t sdslen(const sds s) {
    struct sdshdr *sh = (void*)(s-sizeof *sh);
    return sh->len;
}
個人的にはC言語での文字列操作は慣れてしまっているのでスルーで良いかなと思いましたが、仕組みは面白いと思いました。
Posted at by